﻿var UniverseEntityTypes = {
    UniverseEntity: 0
    , Planet: 1
    , Star: 2
    , SolarSystem: 3
    , Galaxy: 4
    , Universe: 5

    /*Decorative entities like starfields have the type >=1000*/
    , StarField: 1000
    , ShootingStar: 1001
};

var UniverseEntity = function (sizeAndPosition, name, children) {

    //Local variables
    var _childrenEntities = [];
    var _parentEntity = null;

    this.SizeAndPosition = sizeAndPosition;
    this.AssociatedJqObject = null;
    this.AssociatedJqContent = null;
    this.Name = name;
    this.UniverseEntityType = UniverseEntityTypes.UniverseEntity;

    //Public Methods
    this.Center = function () {
        return new Point(
            this.SizeAndPosition.Position.X + this.SizeAndPosition.Size.Width / 2,
            this.SizeAndPosition.Position.Y + this.SizeAndPosition.Size.Height / 2
        );
    };

    this.RelativeCenter = function () {
        return new Point(
            this.SizeAndPosition.Size.Width / 2,
            this.SizeAndPosition.Size.Height / 2
        );
    };

    this.AddChild = function (universeEntity) {
        if (universeEntity == null || $.inArray(universeEntity, _childrenEntities) >= 0)
            null;
        _childrenEntities.push(universeEntity);
        universeEntity.ParentEntity(this, false);
    };

    this.RemoveChild = function (universeEntity) {
        if (universeEntity == null)
            return;
        var pos = $.inArray(universeEntity, _childrenEntities);
        if (pos >= 0)
            _childrenEntities.splice(pos, 1);
    };

    this.AddChildRange = function (universeEntityArray) {
        for (var index in universeEntityArray)
            this.AddChild(universeEntityArray[index]);
    };

    this.Children = function () {
        return _childrenEntities;
    };

    this.ParentEntity = function (parentEntity) {
        if (parentEntity == null)
            return _parentEntity;

        _parentEntity = parentEntity;

        if (Boolean(arguments[1]))
            parentEntity.AddChild(this);
    };

    this.PreviousEntity = function () {
        if (this.ParentEntity() == null)
            return null;

        var children = this.ParentEntity().Children();

        var pos = $.inArray(this, children);
        if (pos <= 0)
            return null;
        return children[pos - 1];
    };

    this.GetAssociatedGalaxy = function (currentEntity) {
        if (currentEntity == null)
            currentEntity = this;

        if (currentEntity.UniverseEntityType > UniverseEntityTypes.Galaxy || currentEntity.ParentEntity() == null)
            return null;

        if (currentEntity.UniverseEntityType == UniverseEntityTypes.Galaxy)
            return currentEntity;

        return this.GetAssociatedGalaxy(currentEntity.ParentEntity());
    };

    this.GetDepth = function () {

        var galaxy = this.GetAssociatedGalaxy();
        var universe = galaxy.ParentEntity();

        var viewDepth = universe == null ? 0 : universe.ViewDepth();

        return galaxy == null ? 0 : galaxy.DepthFactor - viewDepth;

    };

    this.DepthSizeAndPosition = function () {

        //Percent varies between 0 and 2, with decimals
        var percent = this.DepthPercent();

        return new Rectangle(
            new Point(
                this.SizeAndPosition.Position.X + (this.SizeAndPosition.Size.Width * (1 - percent)) / 2
                , this.SizeAndPosition.Position.Y + (this.SizeAndPosition.Size.Height * (1 - percent)) / 2
            )
            , new Size(
                percent * this.SizeAndPosition.Size.Width
                , percent * this.SizeAndPosition.Size.Height
            )
        );
    };

    this.DepthCenter = function () {
        var depthSizeAndPosition = this.DepthSizeAndPosition();
        return new Point(
            depthSizeAndPosition.Position.X + depthSizeAndPosition.Size.Width / 2,
            depthSizeAndPosition.Position.Y + depthSizeAndPosition.Size.Height / 2
        );
    };

    this.DepthRelativeCenter = function () {
        var depthSizeAndPosition = this.DepthSizeAndPosition();
        return new Point(
            depthSizeAndPosition.Size.Width / 2,
            depthSizeAndPosition.Size.Height / 2
        );
    };

    this.DepthPercent = function () {
        var depth = this.GetDepth();
        return depth + 1 < 0 ? 0 : (depth + 1 > 2 ? 2 : depth + 1);
    };

    this.EntityTypeName = function () {
        for (var name in UniverseEntityTypes)
            if (UniverseEntityTypes[name] == this.UniverseEntityType)
                return name;

        return null;
    };

    //Preload Children
    if (children != null && children.length > 0)
        this.AddChildRange(children);
};